package yxy.game.pm2.module.union;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

import org.joda.time.DateTime;
import org.redisson.api.RBucket;

import yxy.apple.util.RandomStringUtility;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.uniondata;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.area.AreaGroupBean;
import yxy.game.pm2.bean.cluster.ClusterBean;
import yxy.game.pm2.bean.module.BaseGameRedisBean;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.bean.module.rank.RankEntry;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;
import yxy.game.pm2.module.union.player.UnionPlayer;
import yxy.game.pm2.module.union.rank.RankActiveUnion;
import yxy.game.pm2.module.union.rank.RankAreaActiveUnion;
import yxy.game.pm2.module.union.rank.RankAreaGroupActiveUnion;

public class UnionBean extends BaseGameRedisBean {
	// bean===========================================================================

	private String code;// 联盟code
	private String name;// 联盟名
	private String abbr;// 缩写
	private int flag;// 旗帜id

	private int level;// 等级
	private long exp;// 经验

	private int serverId;// 所属服务器

	private String notice;// 公告
	private String slogan;// 标语
	private UnionJoinRule joinRule;// 联盟加入规则

	private String leader;// 盟主
	private ArrayList<String> viceList = new ArrayList<>();// 副盟主
	private ArrayList<String> memberList = new ArrayList<>();// 普通成员

	private ArrayList<String> applyList = new ArrayList<>();// 申请列表

	private long power;// 总战力

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAbbr() {
		return abbr;
	}

	public void setAbbr(String abbr) {
		this.abbr = abbr;
	}

	public int getFlag() {
		return flag;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public long getExp() {
		return exp;
	}

	public void setExp(long exp) {
		this.exp = exp;
	}

	public int getServerId() {
		return serverId;
	}

	public void setServerId(int serverId) {
		this.serverId = serverId;
	}

	public String getNotice() {
		return notice;
	}

	public void setNotice(String notice) {
		this.notice = notice;
	}

	public String getSlogan() {
		return slogan;
	}

	public void setSlogan(String slogan) {
		this.slogan = slogan;
	}

	public UnionJoinRule getJoinRule() {
		return joinRule;
	}

	public void setJoinRule(UnionJoinRule joinRule) {
		this.joinRule = joinRule;
	}

	public String getLeader() {
		return leader;
	}

	public void setLeader(String leader) {
		this.leader = leader;
	}

	public ArrayList<String> getViceList() {
		return viceList;
	}

	public void setViceList(ArrayList<String> viceList) {
		this.viceList = viceList;
	}

	public ArrayList<String> getMemberList() {
		return memberList;
	}

	public void setMemberList(ArrayList<String> memberList) {
		this.memberList = memberList;
	}

	public ArrayList<String> getApplyList() {
		return applyList;
	}

	public void setApplyList(ArrayList<String> applyList) {
		this.applyList = applyList;
	}

	public long getPower() {
		return power;
	}

	public void setPower(long power) {
		this.power = power;
	}

	// func==========================================================================

	/** 计算总战力 */
	public long power() {
		long power = 0L;
		for (String playerCode : members()) {
			PlayerBean playerBean = PlayerBean.get(playerCode);
			if (playerBean == null) {
				continue;
			}
			power += playerBean.getPower();
		}
		setPower(power);
		set();
		return power;
	}

	/** 更新活跃 */
	public void active() {
		ServerBean serverBean = ServerBean.get(this.getServerId());
		AreaBean areaBean = AreaBean.get(serverBean.getAreaId());
		AreaGroupBean areaGroupBean = AreaGroupBean.get(areaBean.getGroupId());
		ClusterBean clusterBean = ClusterBean.get(areaBean.getClusterId());

		RankActiveUnion rankActive = new RankActiveUnion(clusterBean.getClusterId());
		long active = DateTime.now().getMillis();
		RankEntry rank = rankActive.get(getCode());
		if (rank != null && rank.getValue() > active) {
			return;
		}

		new RankActiveUnion(clusterBean.getClusterId()).put(getCode(), active);
		RankAreaActiveUnion.get(getServerId()).put(getCode(), active);
		RankAreaGroupActiveUnion.get(areaGroupBean.getGroupId()).put(getCode(), active);
	}

	/** 更新名字 */
	public void name() {
		UnionName.getInstance().add(this);
	}

	/** 成员表 */
	public Set<String> members() {
		Set<String> set = new LinkedHashSet<>();
		set.add(getLeader());
		set.addAll(viceList);
		set.addAll(memberList);
		return set;
	}

	private uniondata data() {
		return DataCenter.getData(getLevel(), uniondata.class);
	}

	/** 总人数上限 */
	public int place() {
		try {
			uniondata data = DataCenter.getData(getLevel(), uniondata.class);
			return data.getNumbermax();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 20;
	}

	public void addexp(int addexp) {
		exp += addexp;
		while (data().getExp() > 0 && exp >= data().getExp()) {
			exp -= data().getExp();
			level++;
		}
		setLevel(level);
		set();
		active();
	}

	public void check() {
		{
			// 有申请者的红点
			boolean haveApply = getApplyList().size() > 0;
			new TipHandle().updateTip(getLeader(), TipType.联盟_有玩家申请, haveApply);
			for (String vice : getViceList()) {
				new TipHandle().updateTip(vice, TipType.联盟_有玩家申请, haveApply);
			}
			for (String member : getMemberList()) {
				new TipHandle().updateTip(member, TipType.联盟_有玩家申请, false);
			}
		}
	}

	// redis==========================================================================

	static public String key(String unionCode) {
		return String.format("UNION:%s:INFO", unionCode);
	}

	static public UnionBean get(String unionCode) {
		if (unionCode == null) {
			return null;
		}
		try {
			UnionBean union = getv(key(unionCode));
			return union;
		} catch (RedisException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void set() {
		try {
			setv(key(getCode()), this);
			check();
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

	static public UnionBean create(PlayerBean playerBean, String name, String abbr, int flag) throws Exception {
		String code = randomUnionCode();
		RBucket<UnionBean> bucket = touchBucket(key(code));
		while (bucket.isExists()) {
			code = randomUnionCode();
			bucket = touchBucket(key(code));
		}
		UnionPlayer unionPlayer = UnionPlayer.get(playerBean.getCode());
		UnionBean union = new UnionBean();
		union.setCode(code);
		union.setLeader(playerBean.getCode());
		union.setServerId(playerBean.getServerId());
		union.setName(name);
		union.setAbbr(abbr);
		union.setFlag(flag);
		union.setJoinRule(UnionJoinRule.defaultUnionJoinRule);// 默认规则
		union.setLevel(1);// 默认1级
		union.setNotice(GameString.联盟默认公告().getText());
		union.setSlogan(GameString.联盟对外宣言().getText());
		union.set();

		unionPlayer.setUnionCode(union.getCode());
		unionPlayer.set();

		union.active();
		union.name();
		return union;
	}

	static private String randomUnionCode() {
		return String.format("uu%s", RandomStringUtility.randomLowerNumeric(10));
	}

	/** 解散后删除实例 */
	static public void remove(String unionCode) {
		try {
			touchBucket(key(unionCode)).delete();
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

	// lock==========================================================================

	@Override
	public String lockKey() {
		return String.format("lock:%s", key(getCode()));
	}
	
	@Override
	public boolean tryLock() throws InterruptedException {
		return super.tryLock();
	}

	public static RedisLock lock(String unionCode) {
		return getLock(String.format("lock:%s", key(unionCode)));
	}
}
